package com.bazaaroid.mobile.android.helper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.ProxySelector;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.bazaaroid.mobile.rest.model.partner.*;

import android.util.Log;

public class BazaaroidApiClient {

	private final static String TAG = "[BazaaroidApiClient]";
	
	private String url;
	private static HttpClient httpClient;
	private static HttpGet httpGet;
	private static HttpResponse httpResponse;
	private HttpEntity httpEntity;
	
	public BazaaroidApiClient(String url)
	{
		this.url = url;
		httpClient = new DefaultHttpClient();
	}
	
	public static boolean isOnline()
	{
		Log.d(TAG, "Checking if phone is online...");
		boolean bOnline = false;
		
		String status = "NULL";
		
		/*Proxy proxy = BazaaroidApiClient.getSystemProxy();
		try 
		{
			URL url = new URL("http://beta-bazaaroid.appspot.com");
			HttpURLConnection urlConnection = (proxy == null) ? 
					(HttpURLConnection)url.openConnection() : (HttpURLConnection)url.openConnection(proxy);
			
			urlConnection.connect();
			InputStream is = urlConnection.getInputStream();
			
			String responseMessage = urlConnection.getResponseMessage();
			int responseCode = urlConnection.getResponseCode();
			if(responseCode == 100)
				status = "OK";
			else
				status = "FAIL";
		} 
		catch (MalformedURLException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch(NumberFormatException e)
		{
			e.printStackTrace();
		}*/
		
		
		//HttpGet hGet = new HttpGet("http://beta-bazaaroid.appspot.com"); // assuming that is always accessible :)
		if(httpGet == null)
			httpGet = new HttpGet("http://beta-bazaaroid.appspot.com");
		//HttpClient hClient = new DefaultHttpClient();
		if(httpClient == null)
			httpClient = new DefaultHttpClient();
		//HttpResponse hResponse;
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			status = httpResponse.getStatusLine().toString();
			Log.d(TAG, String.format("Status: %s", status));
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
		
		if(status.contains("OK"))
		{
			bOnline = true;
		}
		
		return bOnline;
	}
	
	public ArrayList<CategoryItem> retrieveAllCategories()
	{
		ArrayList<CategoryItem> retrievedCategories = null;
		
		httpGet = new HttpGet(url + "/rest/category/all");
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			httpEntity = httpResponse.getEntity();

			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedCategories = xmlParser.parseCategories(inputStream);
                
                /*String xmlResult = parseInputStream(inputStream);
                Log.d(TAG, String.format("Response:\n%s", xmlResult));
 
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedCategories = xmlParser.parseCategories(xmlResult);*/
                
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedCategories;
	}

	public ArrayList<LocationItem> retrieveAllLocations()
	{
		ArrayList<LocationItem> retrievedLocations = null;
		
		httpGet = new HttpGet(url + "/rest/location/all");
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			httpEntity = httpResponse.getEntity();

			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedLocations = xmlParser.parseLocations(inputStream);
 
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedLocations;
	}	
	
	public ArrayList<ActiveDiscountItem> retrieveActiveDiscounts()
	{
		ArrayList<ActiveDiscountItem> retrievedDiscounts = null;
		
		httpGet = new HttpGet(url + "/rest/discount/active");
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			httpEntity = httpResponse.getEntity();

			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedDiscounts = xmlParser.parseActiveDiscounts(inputStream);
 
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedDiscounts;
	}
	
	public ArrayList<ProductItem> retrieveProducts(String query)
	{
		ArrayList<ProductItem> retrievedProducts = null;
		
		httpGet = new HttpGet(url + "/rest/search/products?" + query);
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			
			httpEntity = httpResponse.getEntity();
			
			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedProducts = xmlParser.parseProducts(inputStream);
 
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedProducts;		
	}
	
	public ArrayList<ProductItem> retrieveAllProducts()
	{
		ArrayList<ProductItem> retrievedProducts = null;
		
		httpGet = new HttpGet(url + "/rest/product/all");
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			httpEntity = httpResponse.getEntity();

			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedProducts = xmlParser.parseProducts(inputStream);
 
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedProducts;
	}
	
	/*
	public ArrayList<LocationItem> retrieveAllLocations()
	{
		ArrayList<LocationItem> retrievedLocations = null;
		
		httpGet = new HttpGet(url + "/rest/product/all");
		
		try
		{
			httpResponse = httpClient.execute(httpGet);
			Log.d(TAG, String.format("Status: %s", httpResponse.getStatusLine().toString()));
			
			httpEntity = httpResponse.getEntity();
			
			if(httpEntity != null)
			{
                // Read XML response
                InputStream inputStream = httpEntity.getContent();
                
                
                BazaaroidXmlParser xmlParser = new BazaaroidXmlParser();
                retrievedProducts = xmlParser.parseProducts(inputStream);
 
                // Trigger the connection release
                inputStream.close();
			}
		}
		catch (ClientProtocolException e) 
		{
            Log.e(TAG, String.format("Client protocol exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        } 
		catch (IOException e) 
        {
            Log.e(TAG, String.format("IO exception!\nMessage: %s", (e.getMessage() == null) ? "NULL" : e.getMessage()));
        }
				
		return retrievedProducts;
	}
	*/
    private static String parseInputStream(InputStream inputStream) 
    {
        
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
 
        String readLine = null;
        try 
        {
            while ((readLine = bufferedReader.readLine()) != null) 
            {
            	stringBuilder.append(readLine);
            }

        } 
        catch (IOException ioException) 
        {
            Log.e(TAG, String.format("IO exception thrown while reading the line.\nException message: %s", 
            		(ioException.getMessage() == null) ? "NULL" : ioException.getMessage()));
        } 
        finally 
        {
            try 
            {
            	inputStream.close();
                bufferedReader.close();
            } 
            catch (IOException ioException) 
            {
                Log.e(TAG, String.format("IO exception thrown while performing the close on the input stream and buffered reader.\nException message: %s", 
                		(ioException.getMessage() == null) ? "NULL" : ioException.getMessage()));
            }
        }
        return stringBuilder.toString();
    }
    
    private static Proxy getSystemProxy()
    {
    	System.setProperty("java.net.useSystemProxies", "true");
    	
    	List<Proxy> proxyList = null;
		try 
		{
			proxyList = ProxySelector.getDefault().select(new URI("http://beta-bazaaroid.appspot.com"));
		} 
		catch(URISyntaxException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	return (proxyList != null && proxyList.size() > 0) ? 
    			proxyList.get(0) : new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8080)) ;
    	
    }
}
